﻿using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Runtime.Session;
using Abp.UI;
using SingleUserMall.Authorization.Users;
using SingleUserMall.Common;
using SingleUserMall.Points;
using SingleUserMall.Sign.VO;
using System;
using System.Threading.Tasks;
namespace SingleUserMall.Sign
{
    [AbpAuthorize]
    public class SignAppService : SingleUserMallAppServiceBase, ISignAppService
    {
        private readonly IRepository<UserPoints, long> _userPointsRepository;
        private readonly IRepository<User, long> _userRepository;
        private readonly IRepository<Signed, long> _signedRepository;
        private readonly IRepository<PointRules, long> _pointRulesRepository;
        public SignAppService(
            IRepository<UserPoints, long> userPointsRepository,
            IRepository<User, long> userRepository,
            IRepository<Signed, long> signedRepository,
            IRepository<PointRules, long> pointRulesRepository
            )
        {
            _userPointsRepository = userPointsRepository;
            _userRepository = userRepository;
            _signedRepository = signedRepository;
            _pointRulesRepository = pointRulesRepository;
        }
        public async Task<SignViewVO> GetUserSignRecordAsync()
        {
            var userId = AbpSession.GetUserId();
            var user = _userRepository.FirstOrDefault(userId);
            if(user == null)
            {
                throw new UserFriendlyException("该用户不存在或已被禁用");
            }
            var signed = await _signedRepository.FirstOrDefaultAsync(x=> x.UserId == userId);
            int yesterdayPoint, afterdayPoint;
            var signPoint = CalulatePointAmount(signed, out yesterdayPoint, out afterdayPoint);
            if(signed == null)
            {
                signed = new Signed { SignDays = 0, IsTodaySign = false, IsYesterdaySign = false };
            }
            return signed.ToVO<Signed, SignViewVO>((c, vo) =>
            {
                vo.TotalPoint = user.Points;
                vo.SignPoint = signPoint;
                vo.YesterDaySignPoint = yesterdayPoint;
                vo.AfterDaySignPoint = afterdayPoint;
            });
        }


        private int  CalulatePointAmount(Signed signed,out int yesterdayPoint, out int afterdayPoint)
        {
            var signPoint = 0;
            int normalPoint = 6;
            if (signed == null)
            {
                signPoint = normalPoint;
                yesterdayPoint =  0;
                afterdayPoint = normalPoint+1;
            }
            else
            {
                if(signed.SignTime.Value.Date == DateTime.Now.Date)
                {
                    signed.IsTodaySign = true;
                }
                else
                {
                    signed.IsTodaySign = false;
                }
                if (!signed.IsTodaySign && signed.SignTime.Value.Date == DateTime.Now.Date.AddDays(-1))
                {
                    signed.IsTodaySign = false;
                    signed.IsYesterdaySign = true;
                }
                if(!signed.IsTodaySign && signed.SignTime.Value.Date != DateTime.Now.Date.AddDays(-1))
                {
                    signed.IsTodaySign = false;
                    signed.IsYesterdaySign = false;
                }
                if(!signed.IsYesterdaySign)
                {
                    signed.SignDays = 0;
                }
               if(signed.SignDays == 0)
                {
                    signPoint = normalPoint;
                    yesterdayPoint = 0;
                    afterdayPoint = normalPoint+1;
                }
               else if(signed.SignDays > 0 && signed.SignDays < 6)
                {
                    signPoint = normalPoint + signed.SignDays;
                    yesterdayPoint = signPoint - 1;
                    afterdayPoint = signPoint + 1;
                }
               else
                {
                    signPoint = 12;
                    yesterdayPoint = signed.SignDays == 6? 11 : 12;
                    afterdayPoint = 12;
                }
            }
            return signPoint;
        }

        public async Task<SignViewVO> SignAsync()
        {
            var userId = AbpSession.GetUserId();
            var user = _userRepository.FirstOrDefault(userId);
            var signRecord = await _signedRepository.FirstOrDefaultAsync(x => x.UserId == userId);
            if(signRecord == null)
            {
                _signedRepository.Insert(new Signed
                {
                    UserId = userId,
                    SignTime = DateTime.Now,
                    SignDays = 0,
                    IsTodaySign = true,
                    IsYesterdaySign = false
                });
            }
            else
            {
                if(signRecord.IsTodaySign)
                {
                    throw new UserFriendlyException("今天已经签过到了");
                }

                if (signRecord.SignTime.Value.Date == DateTime.Now.Date.AddDays(-1))
                {
                    signRecord.SignTime = DateTime.Now;
                    signRecord.SignDays+=1 ;
                    signRecord.IsTodaySign = true;
                    signRecord.IsYesterdaySign = true;
                }
                else
                {
                    signRecord.SignTime = DateTime.Now;
                    signRecord.SignDays = 0;
                    signRecord.IsTodaySign = true;
                    signRecord.IsYesterdaySign = false;
                }
            }
            await CurrentUnitOfWork.SaveChangesAsync();
            var signed = await _signedRepository.FirstOrDefaultAsync(x => x.UserId == userId);
            int yesterdayPoint, afterdayPoint;
            var signPoint = CalulatePointAmount(signed, out yesterdayPoint, out afterdayPoint);
            _userPointsRepository.Insert(new UserPoints
            {
                UserId = userId,
                Title = $"签到获得{signPoint}元体验金",
                Points = signPoint,
                Type = UserPointsType.TYJ,
                Status = UserPointsStatus.In,
                FromUserId = userId,
            });
            user.Points += signPoint;
            var sourceUser = _userRepository.FirstOrDefault(x => x.Id == user.SourceUserId);
            if (sourceUser != null)
            {
                OrderManager.CalculateSignOrActivePoint(user, signPoint, "签到", sourceUser);
            }
            return signed.ToVO<Signed, SignViewVO>((c, vo) =>
            {
                vo.TotalPoint = user.Points;
                vo.SignPoint = signPoint;
                vo.YesterDaySignPoint = yesterdayPoint;
                vo.AfterDaySignPoint = afterdayPoint;
            });
        }
    }
}
